#!/bin/sh

#clean up
if [ -e Makefile ]; then
    rm Makefile;
fi

#tmp files
MAKEFILE="$(mktemp)"
UNINSTALL_FILES="$(mktemp)"
UNINSTALL_DIRS="$(mktemp)"

# set default options
PYTHON="/usr/bin/python3"

USR_BIN_FILES="backintime backintime-askpass"

usage () {
    echo "Usage:"
    echo "$0 [--python | --python3 | --python=PYTHON_BINARY]"
    echo ""
    echo "--python"
    echo "\tuse 'python' to start Python3"
    echo "--python3"
    echo "\tuse 'python3' to start Python3"
    echo "--python=PYTHON_BINARY"
    echo "\tuse PYTHON_BINARY to start Python3"
}

addInstallFiles () {
    file=$1
    dest=$2
    mode=$3
    if [ -z "$mode" ]; then
        mode=644
    fi
    for i in $(ls $file); do
        addInstallFile "$i" "$dest" "$mode"
    done
}

addInstallFile () {
    file=$1
    dest=$2
    mode=$3
    if [ -z "$mode" ]; then
        mode=644
    fi
    printf "\tinstall --mode=$mode $file \$(DEST)$dest\n" >> ${MAKEFILE}
    addUninstallFile "$file" "$dest"
}

addSymlink () {
    dst=$1
    src=$2
    printf "\tln --symbolic --force $dst \$(DEST)$src\n" >> ${MAKEFILE}
    addUninstallFile "$src"
}

addInstallFileRename () {
    file=$1
    dest=$2
    mode=$3
    if [ -z "$mode" ]; then
        mode=644
    fi
    printf "\tinstall --mode=$mode $file \$(DEST)$dest\n" >> ${MAKEFILE}
    addUninstallFileRename "$dest"
}

addUninstallFile () {
    if [ $# -eq 2 ]; then
        file=$(basename "$1")
        dest=$2
        path="\$(DEST)$dest/$file"
    else
        path="\$(DEST)$1"
    fi
    printf "\trm -f $path\n" >> ${UNINSTALL_FILES}
}

addUninstallFileRename () {
    file=$1
    printf "\trm -f \$(DEST)$file\n" >> ${UNINSTALL_FILES}
}

addInstallDir () {
    dest=$1
    printf "\tinstall -d \$(DEST)$dest\n" >> ${MAKEFILE}
    addUninstallDir "$dest"
}

addUninstallDir () {
    dest=$1
    printf "\tif [ -d \$(DEST)$dest ]; then rmdir --ignore-fail-on-non-empty \$(DEST)$dest; fi\n" >> ${UNINSTALL_DIRS}
}

addComment () {
    printf "\t# Install $1\n" >> ${MAKEFILE}
    printf "\t# Uninstall files $1\n" >> ${UNINSTALL_FILES}
    printf "\t# Uninstall directory $1\n" >> ${UNINSTALL_DIRS}
}

addNewline () {
    printf "\n" >> ${MAKEFILE}
    printf "\n" >> ${UNINSTALL_FILES}
    printf "\n" >> ${UNINSTALL_DIRS}
}

onTravis () {
    [ "${TRAVIS}" = "true" ]
}

#get commandline arguments
unknown_args=""
for arg in $*; do
    case $arg in
        --python=*)
            PYTHON=$(echo $arg | cut -f2 -d'=')
            ;;
        --python3)
            PYTHON="/usr/bin/python3"
            ;;
        --python)
            PYTHON="/usr/bin/python"
            ;;
        --help | -h) usage; exit 0;;
        *) unknown_args="$unknown_args $arg";;
    esac
done

if [ -n "$unknown_args" ]; then
    echo "Unknown Arguments: $unknown_args"
fi

if [ ! -f "$PYTHON" ]; then
    echo "Warning: \"${PYTHON}\" not found on this computer"
fi

if [ -n "$(sed -e "s#^/usr/bin/python3\? #${PYTHON} #gw /dev/stdout" -i $USR_BIN_FILES)" ]
then
    echo "Replacement of python path with \"${PYTHON}\" successful."
else
    echo "WARNING: Replacement of python path with \"${PYTHON}\" FAILED. Maybe you ran configure more than once?"
fi

#check languages
mos=""
langs=""
for langfile in `ls po/*.po`; do
    lang=`echo $langfile | cut -d/ -f2 | cut -d. -f1`
    mos="po/$lang.mo $mos"
    langs="$lang $langs"
done

#start Makefile
printf "LANGS=$langs\n\n" >> ${MAKEFILE}

printf "PREFIX=/usr\n" >> ${MAKEFILE}
printf "DEST=\$(DESTDIR)\$(PREFIX)\n\n" >> ${MAKEFILE}

printf "all:\tbuild\n\n" >> ${MAKEFILE}

printf "build:\ttranslate compress\n" >> ${MAKEFILE}

printf "clean:\n" >> ${MAKEFILE}
printf "\trm -f po/*.mo\n" >> ${MAKEFILE}
printf "\trm -f man/C/*.gz\n" >> ${MAKEFILE}
printf "\trm -f config-example-*.gz\n" >> ${MAKEFILE}
printf "\trm -rf doc-dev/_build/*\n" >> ${MAKEFILE}
printf "\trm -f .coverage\n" >> ${MAKEFILE}
printf "\trm -rf htmlcov\n" >> ${MAKEFILE}
printf "\n" >> ${MAKEFILE}

# Create install and uninstall target
printf "install:\tinstall_translations\n" >> ${MAKEFILE}
printf "\n\t# Inject version string into source files\n" >> ${MAKEFILE}
printf "\t(cd .. && ./updateversion.sh)\n\n" >> ${MAKEFILE}

addComment "python"
addUninstallDir          "/share/backintime/common/__pycache__"
addUninstallFile "*.pyc" "/share/backintime/common/__pycache__"
addInstallDir            "/share/backintime/common"
addInstallFiles "*.py"   "/share/backintime/common"
addNewline

addComment "plugins"
addUninstallDir                "/share/backintime/plugins/__pycache__"
addUninstallFile "*.pyc"       "/share/backintime/plugins/__pycache__"
addInstallDir                  "/share/backintime/plugins"
addInstallFiles "plugins/*.py" "/share/backintime/plugins"
addUninstallDir                "/share/backintime"
addNewline

addComment "documentation"
addInstallDir                        "/share/doc/backintime-common"
addInstallFile "../debian/copyright" "/share/doc/backintime-common"
addInstallFile "../AUTHORS"          "/share/doc/backintime-common"
addInstallFile "../LICENSE"          "/share/doc/backintime-common"
addInstallFile "../README.md"        "/share/doc/backintime-common"
addInstallFile "../TRANSLATIONS"     "/share/doc/backintime-common"
addInstallFile "../CHANGES"          "/share/doc/backintime-common"
addNewline

addComment "config-examples"
addInstallDir                            "/share/doc/backintime-common/examples"
addInstallFile "config-example-local.gz" "/share/doc/backintime-common/examples"
addInstallFile "config-example-ssh.gz"   "/share/doc/backintime-common/examples"
addUninstallDir                          "/share/doc/backintime-common"
addUninstallDir                          "/share/doc"
addNewline

addComment "man"
addInstallDir                                  "/share/man/man1"
addInstallFile "man/C/backintime.1.gz"         "/share/man/man1"
addInstallFile "man/C/backintime-askpass.1.gz" "/share/man/man1"
addInstallFile "man/C/backintime-config.1.gz"  "/share/man/man1"
addUninstallDir                                "/share/man"
addNewline

addComment "application"
addInstallDir                       "/bin"
addInstallFile "backintime"         "/bin" "755"
addInstallFile "backintime-askpass" "/bin" "755"
addNewline

addComment "autostart"
addInstallDir                       "/../etc/xdg/autostart"
addInstallFile "backintime.desktop" "/../etc/xdg/autostart"
addUninstallDir                     "/../etc/xdg"
addUninstallDir                     "/../etc"
addNewline

addComment "bash-completion"
addInstallDir                       "/share/bash-completion/completions"
addInstallFiles "bash-completion/*" "/share/bash-completion/completions"
addSymlink      "backintime"        "/share/bash-completion/completions/backintime-qt"
addUninstallDir                     "/share/bash-completion"
addNewline

#compress
printf "compress:\n" >> ${MAKEFILE}
printf "\t# Man pages\n" >> ${MAKEFILE}
printf "\tfor i in \$\$(ls -1 man/C/); do case \$\$i in *.gz|*~) continue;; *) gzip -n --best -c man/C/\$\$i > man/C/\$\${i}.gz;; esac; done\n\n" >> ${MAKEFILE}

printf "\t# Config-examples\n" >> ${MAKEFILE}
printf "\tgzip -n --best -c config-example-local > config-example-local.gz\n" >> ${MAKEFILE}
printf "\tgzip -n --best -c config-example-ssh > config-example-ssh.gz\n\n" >> ${MAKEFILE}

#translate
printf "translate:\t$mos\n\n" >> ${MAKEFILE}

for lang in $langs; do
    printf "po/$lang.mo: po/$lang.po\n" >> ${MAKEFILE}
    printf "\tmsgfmt -o po/$lang.mo po/$lang.po\n\n" >> ${MAKEFILE}
done

#common langs
printf "install_translations:\n" >> ${MAKEFILE}
addComment "translations"
for lang in $langs; do
    addInstallDir                      "/share/locale/$lang/LC_MESSAGES"
    addInstallFileRename "po/$lang.mo" "/share/locale/$lang/LC_MESSAGES/backintime.mo"
    addUninstallDir                    "/share/locale/$lang"
done
addUninstallDir "/share/locale"
addUninstallDir "/share"
addNewline

#uninstall
printf "uninstall:\tuninstall_files uninstall_dirs\n\n" >> ${MAKEFILE}
printf "uninstall_files:\n" >> ${MAKEFILE}
cat ${UNINSTALL_FILES} >> ${MAKEFILE}

printf "uninstall_dirs:\n" >> ${MAKEFILE}
cat ${UNINSTALL_DIRS} >> ${MAKEFILE}

#test
for i in "pytest" "py.test-3" "py.test-3.6" "py.test-3.5" "py.test-3.4"; do
    PYTEST=$(which $i 2>/dev/null)
    if [ -n "${PYTEST}" ]; then
        break
    fi
done
COVERAGE=$(which coverage 2>/dev/null)
# Use "coverage run" only on travis-ci.org and if it is available
# this will pass information to coveralls.io.
# Otherwise use "python", "python3" or if available "py.test-3"
if onTravis && [ -n "${COVERAGE}" ]; then
    CMD="coverage run -p"
else
    CMD="${PYTHON}"
fi

printf "test:\tunittest\n\n" >> ${MAKEFILE}
printf "test-v:\tunittest-v\n\n" >> ${MAKEFILE}
for v in "" "-v"; do
    #provide unittests with and without verbosity -v
    printf "unittest${v}:\n" >> ${MAKEFILE}
    if onTravis || [ -z "${PYTEST}" ]; then
        #if running on travis-ci.org or if py.test-3 is not available
        #call every test/test_*.py with $CMD from above
        for i in $(ls -1 test/test_*.py); do
            printf "\t${CMD} -m unittest ${v} -b $i\n" >> ${MAKEFILE}
        done
    else
        #else just call py.test-3 which will find test/test_*.py by itself
        #py.test-3 has a nicer output so this is preferred over simple python3
        printf "\t${PYTEST} ${v}\n" >> ${MAKEFILE}
    fi
    printf "\n" >> ${MAKEFILE}
done

# For details about the "coverage" package args see:
# https://coverage.readthedocs.io/en/stable/cmd.html
printf "coverage:\n" >> ${MAKEFILE}
printf "\tpython3 -m coverage run --source=.,./plugins,../qt,../qt/plugins --omit */test/* -m unittest -b\n" >> ${MAKEFILE}
printf "\tpython3 -m coverage report\n" >> ${MAKEFILE}
printf "\t# To show an interactive HTML coverage report use:\n" >> ${MAKEFILE}
printf "\t# python3 -m coverage html\n" >> ${MAKEFILE}
printf "\t# firefox htmlcov/index.html\n" >> ${MAKEFILE}
printf "\n" >> ${MAKEFILE}

printf "integrationtest:\n" >> ${MAKEFILE}
printf "\ttest/test.sh\n" >> ${MAKEFILE}

#copy Makefile
mv ${MAKEFILE} Makefile
chmod 644 Makefile

#clean up
for i in "${UNINSTALL_FILES}" "${UNINSTALL_DIRS}"; do
    if [ -e "$i" ]; then
        rm "$i"
    fi
done

# check python version
PYTHON_VERSION_REQUIRED="3.8"
PYTHON_VERSION_CURRENT=$(${PYTHON} --version | tr --delete 'Python ')

# Credits: https://unix.stackexchange.com/a/285928/136851
if [ "$(printf '%s\n' "$PYTHON_VERSION_REQUIRED" "$PYTHON_VERSION_CURRENT" | sort -V | head -n1)" != "$PYTHON_VERSION_REQUIRED" ]; then
    printf "Error: Wrong Python version ${PYTHON_VERSION_CURRENT}. "
    printf "But minimal version ${PYTHON_VERSION_REQUIRED} required.\n"
    exit 1
fi

printf "All OK. Now run:\n"
printf "    make\n"
printf "    sudo make install\n"
